package rtcm

import (
	"gitee.com/ymofen/gobase"
	"gitee.com/ymofen/golog"
	"github.com/spf13/cobra"
	"sync"
	"time"
)

type CorbaFreqAndSignalCheckConf struct {
	SubConf       string
	CheckFreqConf string
	CheckSignal   string
	Caption       string
	DurationStr   string
}

func (this *CorbaFreqAndSignalCheckConf) Run() {
	sc := NewSignalChecker()
	defer sc.Close()
	logger := golog.Default()
	if len(this.Caption) > 0 {
		logger = golog.Default().WithOptionEx(golog.WithOptionPrefix(this.Caption))
		sc.SetLogger(logger)
	}
	logger.Infof("SubConf: %s, CheckConf: %s%s, Caption: %s, Duration: %v", this.SubConf, this.CheckFreqConf, this.CheckSignal, this.Caption, this.DurationStr)
	var lk sync.RWMutex
	doneFlag := 0
	sc.UpdateConf(this.SubConf)
	sc.UpdateCheckFreqNameConf(this.CheckFreqConf)
	sc.UpdateCheckSignalConf(this.CheckSignal)
	runDura := gobase.ParseDurationEx(this.DurationStr, time.Second)
	statusFunc := gobase.NewSyncFuncList()
	statusFunc.AddOrSet("status", func(args ...interface{}) {
		lk.RLock()
		defer lk.RUnlock()
		if doneFlag == 1 {
			return
		}
		if sc.GetEpochNum() == 0 {
			logger.Warnf("no epoch data recv!")
		} else {
			logger.Infof("%s", sc.GetStatus())
		}
	})

	tc := time.NewTicker(runDura)
labelFor:
	for {
		ts := time.NewTicker(time.Second * 10)
		select {
		case <-tc.C:
			break labelFor
		case <-ts.C:
			statusFunc.ExecuteFuncs()
		}
	}

	statusFunc.ExecuteAndRemoveAll()
	lk.Lock()
	doneFlag = 1
	lk.Unlock()

}

func getFreqChecker() *cobra.Command {
	conf := &CorbaFreqAndSignalCheckConf{}

	cmd := &cobra.Command{
		Use:  "freqCheck",
		Long: `gnssa rtcm freqCheck --caption="RTCM33GRCEJpro" -i "conntype=ntripclient&connstr=user:pass@103.143.19.54:8003&mp=RTCM33GRCEJpro&blh=30.5,113.31,11.2&interval=10" --checkConf "C2=B1,B3,B2&C3=B1,B3,B2a,B1C&E=E1,E5a,E5b&G=L1,L2,L5&J=L1,L2,L5&R=G1,G2" --runDuration 80s`,
		Run: func(cmd *cobra.Command, args []string) {
			conf.Run()
		},
	}
	cmd.Flags().StringVarP(&conf.SubConf, "subconf", "i", "", "conntype=ntripclient&connstr=user:pass@103.143.19.54:8003&mp=RTCM33GRCEJpro&blh=30.5,113.31,11.2&interval=10")
	cmd.Flags().StringVarP(&conf.CheckFreqConf, "checkConf", "c", "", "C2=B1,B3,B2&C3=B1,B3,B2a,B1C&E=E1,E5a,E5b&G=L1,L2,L5&J=L1,L2,L5&R=G1,G2")
	cmd.Flags().StringVarP(&conf.Caption, "caption", "", "", "caption for log prefix")
	cmd.Flags().StringVarP(&conf.DurationStr, "runDuration", "r", "30s", "10s,1h")
	return cmd
}

func getSignalhecker() *cobra.Command {
	conf := &CorbaFreqAndSignalCheckConf{}

	cmd := &cobra.Command{
		Use: "signalCheck",
		Run: func(cmd *cobra.Command, args []string) {
			conf.Run()
		},
	}
	cmd.Flags().StringVarP(&conf.SubConf, "subconf", "i", "", "conntype=ntripclient&connstr=user:pass@103.143.19.54:8003&mp=RTCM33GRCEJpro&blh=30.5,113.31,11.2&interval=10")
	cmd.Flags().StringVarP(&conf.CheckSignal, "checkConf", "c", "", "C2=2I,6I,7I&C3=1P,2I,5P,6I&E=1C,5Q,7Q&G=1C,2W,5Q&J=1C,2L,5Q&R=1C,2P")
	cmd.Flags().StringVarP(&conf.Caption, "caption", "", "", "caption for log prefix")
	cmd.Flags().StringVarP(&conf.DurationStr, "runDuration", "r", "30s", "10s,1h")
	return cmd
}

func init() {
	gobase.ArgFuncRegister("rtcm", gobase.ArgFuncOption{Catalog: "corbaRoot", Func: func(args string, tag interface{}) (val interface{}, err error) {
		var cmd = &cobra.Command{
			Use: "rtcm",
		}

		cmd.AddCommand(getFreqChecker())
		cmd.AddCommand(getSignalhecker())

		return cmd, nil
	}})

}
